package org.iabako.server.controller.timer.demo;

import org.apache.log4j.Logger;
import org.iabako.server.tools.BundleMessages;
import org.iabako.server.tools.ServerTools;
import org.iabako.shared.entity.business.Expense;
import org.iabako.shared.entity.enumeration.Language;
import org.iabako.shared.entity.enumeration.ExpenseCategory;
import org.iabako.shared.entity.enumeration.ExpenseType;
import org.iabako.shared.entity.enumeration.PaymentMethod;
import org.iabako.shared.entity.user.Enterprise;
import org.iabako.shared.exception.IabakoException;
import org.iabako.shared.iservice.business.ExpenseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by jose on 08/01/15.
 */

@Controller
public class CreateExpenseController {

    static Logger log = Logger.getLogger(CreateClientController.class.getName());

    @Autowired
    ExpenseService expenseService;
    @Autowired
    BundleMessages messages;

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void create(Enterprise enterprise, Language language) throws IOException, URISyntaxException {

        ServerTools serverTools = new ServerTools();
        Date now = new Date();

        Date nMines2 = serverTools.addYearsToDate(now, -2);
        Calendar calendarMines2 = Calendar.getInstance();
        calendarMines2.setTime(nMines2);
        calendarMines2.set(Calendar.DAY_OF_MONTH, 1);

        Date expenseDate = null;
        Integer numberOfExpensePerMonth = 0;
        Integer indexCategory = 0;
        ExpenseCategory expenseCategory = null;

        while (calendarMines2.getTime().compareTo(now) < 0) {
            numberOfExpensePerMonth = new Double(Math.random() * 5).intValue();
            calendarMines2.add(Calendar.MONTH, 1);

            for (int i = 0; i < numberOfExpensePerMonth; i++) {
                indexCategory = new Double(Math.random() * 19).intValue();
                expenseCategory = ExpenseCategory.values()[indexCategory];

                expenseDate = calendarMines2.getTime();
                makeExpense(language, enterprise, expenseCategory, expenseDate, false);
            }
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void createDailyExpenses(Enterprise enterprise, Language language) {
        ServerTools serverTools = new ServerTools();
        Date now = new Date();
        int indexCategory;

        //One payed expense
        indexCategory = new Double(Math.random() * 19).intValue();
        ExpenseCategory expenseCategory = ExpenseCategory.values()[indexCategory];
        makeExpense(language, enterprise, expenseCategory, now, false);

        //One pending expense
        indexCategory = new Double(Math.random() * 19).intValue();
        expenseCategory = ExpenseCategory.values()[indexCategory];
        makeExpense(language, enterprise, expenseCategory, now, true);

        //One future expense
        indexCategory = new Double(Math.random() * 19).intValue();
        expenseCategory = ExpenseCategory.values()[indexCategory];
        makeExpense(language, enterprise, expenseCategory, serverTools.addDaysToDate(now, 10), false);
    }

    private void makeExpense(Language language, Enterprise enterprise, ExpenseCategory expenseCategory, Date expenseDate, boolean pending) {
        Double randomAmount = Math.random() * 800;

        boolean future = new Date().compareTo(expenseDate) < 0;
        Expense expense = Expense.getExpense(new Date().getTime() + "", messages.getLabel(language, expenseCategory.getLabelKey()), ExpenseType.oneShot, null,
                expenseDate, future || pending ? null : PaymentMethod.cash, randomAmount);

        expense.setEnterprise(enterprise);

        try {
            expenseService.save(expense, null);
        } catch (IabakoException e) {
            log.error(e.getMessage(), e);
            //Should never happen
        }
    }
}
